/*###################################################################*
#
# MPGL Engine - CrossPlatform OpenGL Engine
# Copyright (C) 2014  Mitchell Pell
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
####################################################################*/

#ifndef GL_DRIVER_H
#define GL_DRIVER_H

/*! Include Console IO Header */
#if defined(WIN32)
	#include <conio.h>
#else
	#include "../common/conio.h"
#endif

#define ENABLE_MULTITHREAD_BY_DEF

#define GL_DRIVER_DEBUG 3

/*! Include Console for Command/Error Handling */
#include "GLDriverComponents/Console/GLConsole.h"

/*! Include Thread Pool */
#include "GLDriverComponents/Threading/ThreadPoolManager.h"

/*! Include GLApp Header */
#include "../GLApp/GLApp.h"

/*! Include Network Thread Header */
#include "GLDriverComponents/Threading/NetworkThread.h"

/*! Include Logic Thread Header */
#include "GLDriverComponents/Threading/LogicThread.h"

//using namespace mp_error;
using namespace mpgl_engine::driver::threading;

/*! @brief MPGL engine. */
namespace mpgl_engine{ 
	/*! @brief MPGL engine, driver layer. */
	namespace driver { 

	/*!----------------------------------------------------------------
	*	@class		GLDriver
	*	@brief		Driver that is started from main() and runs a
	*				GLApp object.
	*
	*	@author		Mitchell Pell
	*	@date		9/27/2013
	*	@version	1.0
	*
	-----------------------------------------------------------------*/
	class GLDriver
	{

	private:
		/*!------------------------------------------------------------
		*	@var	m_console
		*	@brief	Application console for handling messages, errors,
		*			and even commands.
		*
		*/
		GlConsole*			m_console;

		/*!------------------------------------------------------------
		*	@var	m_threadPool
		*	@brief	Thread pool manager for the entire application.
		*/
		ThreadPoolManager*	m_threadPool;

		/*!------------------------------------------------------------
		*	@var	m_glApp
		*	@brief	The Starting point for the application.
		*	@note	This is an abstract class and requires an overridden
		*			version of your own.
		*/
		GLApp*				m_glApp;

		/*!------------------------------------------------------------
		*	@var	m_networkThread
		*	@brief	Thread for managing the network.
		*/
		NetworkThread*		m_networkThread;

		/*!------------------------------------------------------------
		*	@var	m_logicThread
		*	@brief	Thread for managing any logic.
		*/
		LogicThread*		m_logicThread;

		bool				m_networkThreadingEnabled;
		bool				m_logicThreadingEnabled;

	public:

		/*!------------------------------------------------------------
		*	@fn		GLDriver()	
		*	@brief	Default Constructor
		*/
		GLDriver( GLApp* app = NULL,
#ifdef ENABLE_MULTITHREAD_BY_DEF
			bool enableLogicThread = true, 
			bool enableNetworkThread = true);
#else
			bool enableLogicThread = false, 
			bool enableNetworkThread = false);
#endif

		/*!------------------------------------------------------------
		*	@fn		GLDriver(GLApp* app)	
		*	@brief	Overloaded Constructor
		*/

		//GLDriver(GLApp* app);

		/*!------------------------------------------------------------
		*	@fn		 ~GLDriver()	
		*	@brief	 Destructor
		*/
		~GLDriver();

		/*!------------------------------------------------------------
		*	@fn		SetDriver(GLApp* app)
		*	@brief	Sets the Application
		*/
		void SetApplication(GLApp* app);

		/*!------------------------------------------------------------
		*	@fn		GetDriver()	
		*	@brief	Gets the current Application
		*/

		GLApp* GetDriver(){return m_glApp;}

		/*!------------------------------------------------------------
		*	@fn		Run()	
		*	@brief	Runs the Application
		*/
		virtual int Run();

		GlConsole* GetConsole() const { return m_console; }

	private:
		void InitializeConsoleHandler();
		void InitializeThreadPool();
		void InitializeThreads();
	};
}}

#endif